package com.lvmama.task.common.utils;


import com.lvmama.task.common.vo.Task;
import org.apache.commons.lang3.time.DurationFormatUtils;
import org.apache.commons.lang3.time.FastDateFormat;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.quartz.CronTrigger;
import org.quartz.TriggerUtils;
import sun.misc.Regexp;

import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.NetworkInterface;
import java.net.UnknownHostException;
import java.text.ParseException;
import java.util.*;

import static com.danga.MemCached.MemCachedClient.log;

/**
 * Created by IntelliJ IDEA.<p/>
 * User: troy-kou<p/>
 * Date: 15/3/25<p/>
 * Time: 下午3:41<p/>
 * Email:kouhongyu@163.com<p/>
 */
public class TaskUtil {

    private static Log log = LogFactory.getLog(TaskUtil.class);

    /**
     * 计算下一次的运行时间
     * @param task
     * @return
     * @throws ParseException
     */
    public static Date calculateNextRunTime(Task task) throws ParseException {

        Calendar nowTime = Calendar.getInstance();

        //运行时间
        Calendar nextTime = Calendar.getInstance();

        if (!task.getCycle().equals(Task.TASK_CYCLE.CRON.getCode())) {
            nextTime.setTime((Date) task.getPlanTime().clone());
        }

        //Cron表达式
        if (task.getCycle().equals(Task.TASK_CYCLE.CRON.getCode())) {
            CronTrigger cronTrigger = new CronTrigger();
            cronTrigger.setCronExpression(task.getCronExpression());

            List<Date> dates = TriggerUtils.computeFireTimes(cronTrigger, null, 1);

            nextTime.setTime(dates.get(0));
        }
        //秒
        else if (task.getCycle().equals(Task.TASK_CYCLE.SECOND.getCode())) {

            nextTime.set(Calendar.YEAR, nowTime.get(Calendar.YEAR));
            nextTime.set(Calendar.MONTH, nowTime.get(Calendar.MONTH));
            nextTime.set(Calendar.DAY_OF_MONTH, nowTime.get(Calendar.DAY_OF_MONTH));
            nextTime.set(Calendar.HOUR_OF_DAY, nowTime.get(Calendar.HOUR_OF_DAY));
            nextTime.set(Calendar.MINUTE, nowTime.get(Calendar.MINUTE));
            nextTime.set(Calendar.SECOND, nowTime.get(Calendar.SECOND));

            nextTime.add(Calendar.SECOND, task.getCycleDimension().intValue());
        }
        //分钟
        else if (task.getCycle().equals(Task.TASK_CYCLE.MINUTE.getCode())) {

            nextTime.set(Calendar.YEAR, nowTime.get(Calendar.YEAR));
            nextTime.set(Calendar.MONTH, nowTime.get(Calendar.MONTH));
            nextTime.set(Calendar.DAY_OF_MONTH, nowTime.get(Calendar.DAY_OF_MONTH));
            nextTime.set(Calendar.HOUR_OF_DAY, nowTime.get(Calendar.HOUR_OF_DAY));
            nextTime.set(Calendar.MINUTE, nowTime.get(Calendar.MINUTE));

            nextTime.add(Calendar.MINUTE, task.getCycleDimension().intValue());
        }
        //小时
        else if (task.getCycle().equals(Task.TASK_CYCLE.HOURS.getCode())) {

            nextTime.set(Calendar.YEAR, nowTime.get(Calendar.YEAR));
            nextTime.set(Calendar.MONTH, nowTime.get(Calendar.MONTH));
            nextTime.set(Calendar.DAY_OF_MONTH, nowTime.get(Calendar.DAY_OF_MONTH));
            nextTime.set(Calendar.HOUR_OF_DAY, nowTime.get(Calendar.HOUR_OF_DAY));

            nextTime.add(Calendar.HOUR_OF_DAY, task.getCycleDimension().intValue());
        }
        //天
        else if (task.getCycle().equals(Task.TASK_CYCLE.DAY.getCode())) {

            nextTime.set(Calendar.YEAR, nowTime.get(Calendar.YEAR));
            nextTime.set(Calendar.MONTH, nowTime.get(Calendar.MONTH));
            nextTime.set(Calendar.DAY_OF_MONTH, nowTime.get(Calendar.DAY_OF_MONTH));

            nextTime.add(Calendar.DAY_OF_MONTH, task.getCycleDimension().intValue());
        }
        //月
        else if (task.getCycle().equals(Task.TASK_CYCLE.MONTH.getCode())) {
            nextTime.set(Calendar.YEAR, nowTime.get(Calendar.YEAR));
            nextTime.set(Calendar.MONTH, nowTime.get(Calendar.MONTH));

            nextTime.add(Calendar.MONTH, task.getCycleDimension().intValue());
        }
        //年
        else if (task.getCycle().equals(Task.TASK_CYCLE.YEAR.getCode())) {
            nextTime.set(Calendar.YEAR, nowTime.get(Calendar.YEAR));

            nextTime.add(Calendar.YEAR, task.getCycleDimension().intValue());
        }
        //每周几运行
        else if (task.getCycle().equals(Task.TASK_CYCLE.WEEK.getCode())) {
            //先把日期设置为今天，时间不动
            nextTime.set(Calendar.YEAR, nowTime.get(Calendar.YEAR));
            nextTime.set(Calendar.MONTH, nowTime.get(Calendar.MONTH));
            nextTime.set(Calendar.DAY_OF_MONTH, nowTime.get(Calendar.DAY_OF_MONTH));

            //一周中每一天对应的数字
            Map<Integer, Task.WEEK> weekMap = new HashMap<Integer, Task.WEEK>();
            weekMap.put(1, Task.WEEK.SUNDAY);
            weekMap.put(2, Task.WEEK.MONDAY);
            weekMap.put(3, Task.WEEK.TUESDAY);
            weekMap.put(4, Task.WEEK.WEDNESDAY);
            weekMap.put(5, Task.WEEK.THURSDAY);
            weekMap.put(6, Task.WEEK.FRIDAY);
            weekMap.put(7, Task.WEEK.SATURDAY);

            boolean ok = false;

            while (!ok) {
                //看看这一天是不是要运行
                if (task.getWeek().contains(weekMap.get(nextTime.get(Calendar.DAY_OF_WEEK)).getCode())) {
                    //如果今天的运行时间已经过了，日期加一天
                    if (nowTime.getTimeInMillis() > nextTime.getTimeInMillis()) {
                        nextTime.add(Calendar.DAY_OF_MONTH, 1);
                    } else {//刚好今天运行，时间还没过，那么就是这个时间了
                        ok = true;
                    }
                } else {//今天不运行，日期加一天
                    nextTime.add(Calendar.DAY_OF_MONTH, 1);
                }
            }
        }

        return nextTime.getTime();
    }

    public static List<String> localIPs() {
        List<String> ipList = new ArrayList<String>();

        try {
            Enumeration allNetInterfaces = NetworkInterface.getNetworkInterfaces();
            InetAddress ip;
            while (allNetInterfaces.hasMoreElements()) {
                NetworkInterface netInterface = (NetworkInterface) allNetInterfaces.nextElement();
                Enumeration addresses = netInterface.getInetAddresses();
                while (addresses.hasMoreElements()) {
                    ip = (InetAddress) addresses.nextElement();
                    if (ip != null && ip instanceof Inet4Address && !"127.0.0.1".equals(ip.getHostAddress())) {
                        ipList.add(ip.getHostAddress());
                    }
                }
            }
        } catch (Exception e) {
            log.error(e);
        }
        return ipList;
    }

    public static String hostName() {
        try {
            return (InetAddress.getLocalHost()).getHostName();
        } catch (UnknownHostException uhe) {
            String host = uhe.getMessage();
            if (host != null) {
                int colon = host.indexOf(':');
                if (colon > 0) {
                    return host.substring(0, colon);
                }
            }
            return "UnknownHost";
        }
    }

    public static String calculateTimeConsumingFormat(Long timeConsuming) {
        String timeConsumingFormat = timeConsuming == null ? "" : DurationFormatUtils.formatDurationHMS(timeConsuming);

        timeConsumingFormat = timeConsumingFormat.replaceAll("^0:", "").replaceAll("^00:", "").replaceAll("^00", "");

        return timeConsumingFormat;
    }
    public static String generateInterruptKey(Long logId) {
        return "TASK_JOB_INTERRUPT_KEY_" + logId;
    }

    public static void main(String[] args) {
        long s1 = 1000L;
        System.out.println(s1*1);
        System.out.println(s1*5);
        System.out.println(s1*10);
        System.out.println(s1*15);
        System.out.println(s1*30);
        System.out.println(s1*60*1);
        System.out.println(s1*60*5);
        System.out.println(s1*60*10);
        System.out.println(s1*60*15);
        System.out.println(s1*60*30);
        System.out.println(s1*60*60*1);
        System.out.println(s1*60*60*2);
        System.out.println(s1*60*60*3);
        System.out.println(s1*60*60*6);
        System.out.println(s1*60*60*12);
    }
}
